`timescale 1ns/1ps

module  rptr_empty(
                      //output
                    	 ef,
                    	 rp_bin,
                    	 rp_gray,
                    	 
                      //input
                       rd_clk, 
                       rd_rst,
                       rd_clr,
                       ren,
                       wp_s
                     );

  parameter aw=10;
  
  output			ef;              //low active
  output [aw:0]   rp_bin;
  output [aw:0]   rp_gray;
  

  input		      	rd_clk;      
  input		      	rd_rst;     //low active
  input		       	rd_clr;     //high active 
  input           ren;       
  input [aw:0]    wp_s;
  
///////////////////////////////////////////////////////////////////////
//
//	local wires
//

  reg	ef;              //low active
  reg   [aw:0]   	rp_gray;
  reg	[aw:0]   	rp_bin;   
  wire	[aw:0]		rp_bin_next;  
  wire	[aw:0]		rp_gray_next;
   
///////////////////////////////////////////////////////////////////////
//  read pointers logic
//  

always @(posedge rd_clk or negedge rd_rst)
if(!rd_rst)	
	rp_bin <= #1 {aw+1{1'b0}};
else if(rd_clr)
	rp_bin <= #1 {aw+1{1'b0}};
else if(!ren)
	rp_bin <= #1 rp_bin_next;

always @(posedge rd_clk or negedge rd_rst)
if(!rd_rst)	
	rp_gray <= #1 {aw+1{1'b0}};
else if(rd_clr)	
	rp_gray <= #1 {aw+1{1'b0}};
else if(!ren)
	rp_gray <= #1 rp_gray_next;

assign rp_bin_next  = rp_bin + {{aw{1'b0}},1'b1};
assign rp_gray_next = rp_bin_next ^ {1'b0, rp_bin_next[aw:1]};

//synopsys translate_off
//--------------Only for Debug/Statistics-------------------
wire [aw:0]	wp_bin_rd_s;
assign wp_bin_rd_s = wp_s ^ {1'b0, wp_bin_rd_s[aw:1]};
reg [aw:0] rd_status;
always @(posedge rd_clk or negedge rd_rst)
if(!rd_rst)	
	rd_status <= #1 {aw+1{1'b0}};
else if(rd_clr)	
	rd_status <= #1 {aw+1{1'b0}};
else
	rd_status <= #1 wp_bin_rd_s - rp_bin;
//synopsys translate_on

///////////////////////////////////////////////////////////////////////
//  empty flag logic
//  
always @(posedge rd_clk or negedge rd_rst)
if(!rd_rst)	
	ef <= #1 0;
else if(rd_clr)	
	ef <= #1 0;
else 
	ef <= #1 ~((wp_s == rp_gray) | (!ren & (wp_s == rp_gray_next)));
	       
endmodule	        
